﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Weight.Controls
{
    public partial class LYFMenu : UserControl
    {
        public LYFMenu()
        {
            this.DoubleBuffered = true;//设置本窗体
            this.SetStyle(
                      //ControlStyles.UserPaint |    //使用自定义的绘制方式
                      ControlStyles.ResizeRedraw//当控件大小发生变化时就重新绘制
                    | ControlStyles.SupportsTransparentBackColor//则控件接受 alpha 组件数小于 255 个的 BackColor 来模拟透明度
                    | ControlStyles.AllPaintingInWmPaint//则控件忽略窗口消息 WM_ERASEBKGND 以减少闪烁
                    | ControlStyles.OptimizedDoubleBuffer//则控件将首先绘制到缓冲区而不是直接绘制到屏幕，这可以减少闪烁
                    | ControlStyles.DoubleBuffer
                    , true);

            InitializeComponent();
            this.ForeColor = Color.White;
            panelBack = new LYFPanel();
        }

        #region 属性
        [System.ComponentModel.Browsable(true)]
        public int RootIndex { get; set; } = 0;
        [System.ComponentModel.Browsable(true)]
        public int ChildIndex { get; set; } = 0;

        private Color _childPanelBackColor;
        [System.ComponentModel.Browsable(true)]
        public Color ChildPanelBackColor { get => _childPanelBackColor; set => _childPanelBackColor = value; }

        private Color _titleBackColor = Color.FromArgb(00, 0xa3, 0x81);
        [System.ComponentModel.Browsable(true)]
        public Color TitleBackColor { get => _titleBackColor; set => _titleBackColor = value; }

        private Color _childBackColor = Color.FromArgb(00, 0xa3, 0x81);
        [System.ComponentModel.Browsable(true)]
        public Color ChildBackColor { get => _childBackColor; set => _childBackColor = value; }

        private Color _backColor = Color.White;
        [System.ComponentModel.Browsable(true)]
        [DefaultValue(typeof(Color), "Color.White")]
        public new Color BackColor
        {
            get
            {
                return panelBack.BackColor;
            }
            set
            {
                _backColor = value;
                if (panelBack != null)
                    panelBack.BackColor = _backColor;
                this.Invalidate();
            }
        }

        #endregion

        #region 自定义
        public List<CoolMenuGroupInfo> MenuGroup = new List<CoolMenuGroupInfo>();
        #endregion
        private LYFPanel panelBack;

        private void CoolMenu_Load(object sender, EventArgs e)
        {

            panelBack.Dock = DockStyle.Fill;
            panelBack.AutoScroll = true;
            this.Controls.Add(panelBack);
        }

        //protected override CreateParams CreateParams
        //{
        //    get
        //    {
        //        CreateParams cp = base.CreateParams;
        //        cp.ExStyle |= 0x02000000;
        //        return cp;
        //    }
        //}

        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.FillRectangle(new SolidBrush(_backColor), e.ClipRectangle);
            base.OnPaint(e);
        }


        public void Add(string text = null, Image image = null)
        {
            LYFMenuButton coolBtn = new LYFMenuButton();
            coolBtn.Name = "CoolMenuButton" + RootIndex;
            coolBtn.Index = RootIndex;
            if (text != null)
                coolBtn.Text = text;
            else
                coolBtn.Text = coolBtn.Name;
            if (image != null)
                coolBtn.Image = image;
            coolBtn.AutoSize = false;
            coolBtn.Level = 0;
            coolBtn.ForeColor = this.ForeColor;
            coolBtn.Height = 40;
            coolBtn.BackColor = _titleBackColor;
            coolBtn.RootClick += CoolBtn_RootClick;
            LYFPanel panel = new LYFPanel();
            panel.Dock = DockStyle.Top;
            panel.Height = 1;
            panel.Visible = false;
            panel.BackColor = this.ChildPanelBackColor;
            MenuGroup.Add(new CoolMenuGroupInfo(coolBtn, panel));
            panelBack.Controls.Add(coolBtn);
            panelBack.Controls.Add(panel);

            coolBtn.BringToFront();
            panel.BringToFront();
            RootIndex++;
        }

        private void CoolBtn_RootClick(object sender, LYFMenuButton.ClickEventArgs e)
        {
            //焦点
            MenuGroup.Where(w => w.CoolMenuButton.Level == 0 && w.CoolMenuButton.Index != e.Index).ToList().ForEach(f =>
            {
                f.CoolMenuButton.IsFocus = false;
                f.CoolMenuButton.BackColor = Color.FromArgb(255, e.BackColor);
            });
            (sender as LYFMenuButton).BackColor = Color.FromArgb(200, e.BackColor);
            //
            MenuGroup.ForEach(f =>
            {
                if (f.CoolMenuButton.Expanded && f.CoolMenuButton.Index != e.Index)
                {
                    ThreadPool.QueueUserWorkItem(o => CoolPanelCollapseStyle(o), f.CoolPanel);
                    //f.CoolPanel.Visible = false;
                    f.CoolMenuButton.Expanded = false;
                }

            });
            if (e.Expanded)
            {
                var groupInfo = MenuGroup.FirstOrDefault(q => q.CoolMenuButton.Level == 0 && q.CoolMenuButton.Index == e.Index);
                if (groupInfo != null)
                {
                    groupInfo.CoolPanel.Visible = true;
                    ThreadPool.QueueUserWorkItem(o => CoolPanelExpandedStyle(o), groupInfo.CoolPanel);
                    groupInfo.CoolMenuButton.Expanded = true;
                }
            }
            else
            {
                var groupInfo = MenuGroup.FirstOrDefault(q => q.CoolMenuButton.Level == 0 && q.CoolMenuButton.Index == e.Index);
                if (groupInfo != null)
                {
                    ThreadPool.QueueUserWorkItem(o => CoolPanelCollapseStyle(o), groupInfo.CoolPanel);
                    groupInfo.CoolMenuButton.Expanded = false;
                }
            }
        }
        private void CoolBtn_ChildClick(object sender, LYFMenuButton.ClickEventArgs e)
        {
            //焦点
            MenuGroup.ForEach(f =>
            {
                var controls = f.CoolPanel.Controls;
                if (controls.Count > 0)
                {
                    foreach (LYFMenuButton btn in controls)
                    {
                        if (btn.IsFocus)
                        {
                            btn.IsFocus = false;
                            btn.BackColor = Color.FromArgb(255, e.BackColor);
                        }
                    }
                }
            });
            (sender as LYFMenuButton).IsFocus = true;
            (sender as LYFMenuButton).BackColor = Color.FromArgb(150, e.BackColor);
            var item = MenuGroup.FirstOrDefault(q => q.CoolPanel.Controls.Find(e.Name, false).Length > 0);
            ChildClick?.Invoke(this, new ChildClickEventArgs()
            {
                ParentText = item.CoolMenuButton.Text,
                Text = e.Text
            });
        }
        private void CoolPanelExpandedStyle(object obj)
        {
            LYFPanel p = obj as LYFPanel;
            this.Invoke((Action)delegate
            {
                p.Height = 1;
            });
            int height = 1;
            var controls = p.Controls;
            if (controls.Count > 0)
            {
                height = controls.Count * ((LYFMenuButton)controls[0]).Height;
                for (int i = 0; i < (height / 20) + 1; i++)
                {
                    this.Invoke((Action)delegate
                    {
                        p.Height += 20;
                        if (p.Height > height)
                            p.Height = height;
                    });
                    Thread.Sleep(10);
                }
            }
            else
            {
                this.Invoke((Action)delegate
                {
                    p.Height = 1;
                });
            }
        }

        private void CoolPanelCollapseStyle(object obj)
        {
            LYFPanel p = obj as LYFPanel;
            int count = p.Height;

            for (int i = 1; i < (count / 20) + 1; i++)
            {
                this.Invoke((Action)delegate
                {
                    if (p.Height > 20)
                        p.Height -= 20;
                    else
                        p.Height = 1;
                });
                Thread.Sleep(10);
            }
            this.Invoke((Action)delegate
            {
                p.Visible = false;
            });
        }

        public void AddChild(string parentText, string text, Image image = null)
        {
            CoolMenuGroupInfo groupInfo = MenuGroup.FirstOrDefault(q => q.CoolMenuButton.Text == parentText);
            if (groupInfo != null)
            {
                LYFPanel panel = groupInfo.CoolPanel;
                LYFMenuButton coolBtn = new LYFMenuButton();
                coolBtn.Name = "CoolMenuButtonChild" + ChildIndex;
                coolBtn.Index = ChildIndex;
                if (text != null)
                    coolBtn.Text = text;
                else
                    coolBtn.Text = coolBtn.Name;
                if (image != null)
                    coolBtn.Image = image;
                coolBtn.AutoSize = false;
                coolBtn.Level = 1;
                coolBtn.Height = 35;
                coolBtn.ForeColor = this.ForeColor;
                coolBtn.BackColor = _childBackColor;
                coolBtn.ChildClick += CoolBtn_ChildClick;
                panel.Controls.Add(coolBtn);
                coolBtn.BringToFront();
                panel.Height = panel.Controls.Count * coolBtn.Height + 1;
                ChildIndex++;
            }
        }

        public bool Exist(string text)
        {
            if (MenuGroup.Count > 0)
            {
                if (MenuGroup.FirstOrDefault(q => q.CoolMenuButton.Text == text) != null)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 展开和折叠
        /// </summary>
        /// <param name="isOpen"></param>
        public void Exspan(bool isOpen)
        {
            if (isOpen)
            {
                var groupInfos = MenuGroup.Where(q => q.CoolMenuButton.Level == 0 );
                foreach(var groupInfo in groupInfos)
                {
                    if (groupInfo != null)
                    {
                        groupInfo.CoolPanel.Visible = true;
                        ThreadPool.QueueUserWorkItem(o => CoolPanelExpandedStyle(o), groupInfo.CoolPanel);
                        groupInfo.CoolMenuButton.Expanded = true;
                    }
                }
                
            }
            else
            {
                var groupInfos = MenuGroup.Where(q => q.CoolMenuButton.Level == 0 );
                foreach(var groupInfo in groupInfos)
                {
                    if (groupInfo != null)
                    {
                        ThreadPool.QueueUserWorkItem(o => CoolPanelCollapseStyle(o), groupInfo.CoolPanel);
                        groupInfo.CoolMenuButton.Expanded = false;
                    }
                }
              
            }
        }

        public void SetSkin(Color color)
        {
            BackColor = color;
            TitleBackColor = color;
            ChildBackColor = color;
            ChildPanelBackColor = color;
        }

        public void Clear()
        {
            MenuGroup.Clear();
            this.panelBack.Controls.Clear();
        }

        public class CoolMenuGroupInfo
        {
            public CoolMenuGroupInfo(LYFMenuButton coolMenuButton, LYFPanel coolPanel)
            {
                CoolMenuButton = coolMenuButton;
                CoolPanel = coolPanel;
            }
            public LYFMenuButton CoolMenuButton { get; set; }
            public LYFPanel CoolPanel { get; set; }
        }

        public event EventHandler<ChildClickEventArgs> ChildClick;
        public class ChildClickEventArgs : EventArgs
        {
            public string ParentText { get; set; }
            public string Text { get; set; }
        }


    }
}
